package com.jeecg.demo.api;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;

import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.sql.CallableStatement;
import java.sql.SQLException;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.validation.ConstraintViolation;
import javax.validation.Validator;

import net.sf.json.JSONObject;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.xmlbeans.impl.common.IOUtil;
import org.hibernate.Session;
import org.jeecgframework.core.beanvalidator.BeanValidators;
import org.jeecgframework.core.util.ApplicationContextUtil;
import org.jeecgframework.core.util.IpUtil;
import org.jeecgframework.core.util.LogUtil;
import org.jeecgframework.core.util.MyBeanUtils;
import org.jeecgframework.core.util.PasswordUtil;
import org.jeecgframework.core.util.StringUtil;
import org.jeecgframework.core.util.oConvertUtils;
import org.jeecgframework.jwt.def.JwtConstants;
import org.jeecgframework.jwt.model.TokenModel;
import org.jeecgframework.jwt.service.TokenManager;
import org.jeecgframework.jwt.util.ResponseMessage;
import org.jeecgframework.jwt.util.Result;
import org.jeecgframework.web.system.service.SystemService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.orm.hibernate4.SessionFactoryUtils;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.util.UriComponentsBuilder;

import com.alibaba.fastjson.JSONArray;
import com.jeecg.demo.entity.AppAboutEntity;
import com.jeecg.demo.entity.AppUserEntity;
import com.jeecg.demo.entity.AppVersionEntity;
import com.jeecg.demo.entity.SysAppRegionEntity;
import com.jeecg.demo.entity.SysUserEntity;
import com.jeecg.demo.service.AppAboutServiceI;
import com.jeecg.demo.service.AppUserServiceI;
import com.jeecg.demo.util.MD5;

/**
 * @Title: Controller
 * @Description: login and register interface
 * @author onlineGenerator
 * @date 2019-06-10 14:58:22
 * @version V1.0
 * 
 */
@Api(value = "AppUser", description = "user normal operation", tags = "appUser")
@Controller
@RequestMapping("/appUser")
public class AppUser {
	private static final Logger logger = LoggerFactory.getLogger(AppUser.class);

	@Autowired
	private SystemService systemService;
	@Autowired
	private AppUserServiceI appuserSerive;
	@Autowired
	private AppAboutServiceI appAboutSerive;
	@Autowired
	private Validator validator;
	@Autowired
	private TokenManager tokenManager;

	/**
	 * 加载页
	 * 
	 * @param phoneNum
	 * @return
	 */
	@RequestMapping(value = "/getLoadingPage", method = RequestMethod.GET)
	@ResponseBody
	@ApiOperation(value = "加载页", produces = "application/json", httpMethod = "GET")
	public ResponseMessage<?> getLoadingPage() {
		String sql = "select APP_LOADING_ID,PIC_PATH  from app_loading where ISVAILD=1";
		List<Map<String, Object>> listMap = systemService
				.findForJdbc(sql, null);
		return Result.success(listMap);
	}
	
	/**
	 * check phonenumber
	 * 
	 * @param phoneNum
	 * @return
	 */
	@RequestMapping(value = "/checkPhone", method = RequestMethod.GET)
	@ResponseBody
	@ApiOperation(value = "chenck phone number", produces = "application/json", httpMethod = "GET")
	public ResponseMessage<?> checkPhone(
			@RequestParam("phoneNum") String phoneNum) {
		String sql = "select count(*) as num from v_ecp_user where loginname=?";
		Long count = systemService.getCountForJdbcParam(sql, phoneNum);

		return Result.success(count);
	}
	
	
	@RequestMapping(value = "/checkUser", method = RequestMethod.POST)
	@ResponseBody
	@ApiOperation(value = "checkUser", produces = "application/json", httpMethod = "POST")
	public ResponseMessage<?> checkUser(HttpServletRequest request,
			@RequestParam() String loginName, @RequestParam() String appToken
			) {
		if (StringUtils.isNotEmpty(loginName)&&StringUtils.isNotEmpty(appToken)) {
			TokenModel model = tokenManager.getToken(appToken, loginName);
			boolean checkToken = tokenManager.checkToken(model);
			if (checkToken) {
				return Result.success();
			}
		}
		return Result.error();
	}

	/**
	 * get province information
	 * 
	 * @return
	 */
	@RequestMapping(value = "/getProvicne", method = RequestMethod.GET)
	@ResponseBody
	@ApiOperation(value = "get province information", produces = "application/json", httpMethod = "GET")
	public ResponseMessage<?> getProvicne() {
		String sql = "SELECT * FROM sys_app_region where parentcode='01100000'";

		List<Map<String, Object>> listMap = systemService
				.findForJdbc(sql, null);
		return Result.success(listMap);
	}

	/**
	 * get city list
	 * 
	 * @pram provicen id
	 * @return
	 */
	@RequestMapping(value = "/getcity", method = RequestMethod.GET)
	@ResponseBody
	@ApiOperation(value = "get city list", produces = "application/json", httpMethod = "GET")
	public ResponseMessage<?> getcity(@RequestParam("parentId") String parentId) {
		String sql = "SELECT * FROM sys_app_region where parentcode=?";

		List<Map<String, Object>> listMap = systemService.findForJdbc(sql,
				parentId);
		return Result.success(listMap);
	}

	/**
	 * 登录描述
	 * 
	 * @return
	 */
//	@RequestMapping(value = "/getLoginDesc", method = RequestMethod.GET)
//	@ResponseBody
//	@ApiOperation(value = "登录描述", produces = "application/json", httpMethod = "GET")
//	public ResponseMessage<?> getLoginDesc() {
//		String desc=PropertiesUtil.getPropertiesValue("desc");
//		logger.info("登录描述-------------------------" + desc);
//		return Result.success(desc);
//	}
//
//	public String getCertStream(String path) {
//		try {
//			ClassPathResource classPathResource = new ClassPathResource(path);
//			// 获取文件流
//			InputStream stream = classPathResource.getInputStream();
//			byte[] content = IOUtils.toByteArray(stream);
//			String strRead = new String(content);
//			stream.read(content);
//			stream.close();
//			strRead = String.copyValueOf(strRead.toCharArray(), 0,
//					content.length);
//			return strRead;
//		} catch (IOException e) {
//			e.printStackTrace();
//		}
//		return "";
//	}

	@RequestMapping(value = "/regist", method = RequestMethod.POST)
	@ResponseBody
	public ResponseMessage<?> register(HttpServletRequest request) {
		float result =-1;
		String phone = request.getParameter("phone");
		String password = request.getParameter("password");
		String proVince = request.getParameter("proVince");
		String city = request.getParameter("city");
		city = StringUtils.isNotEmpty(city) ? city : proVince;
		String username = request.getParameter("username");
		String workspace = request.getParameter("workspace");
		String usertype = request.getParameter("usertype");
		Session session = systemService.getSession();//get jdbc session 
		//ps.by this way get the session class from hibernatejdbc.
		//Want more detail.See GenericBaseCommonDao.java
		CallableStatement procCall;
		try {
			procCall = SessionFactoryUtils.getDataSource(session.getSessionFactory()).getConnection().prepareCall("{call app_userregister2(?,?,?,?,?,?)}");
			procCall.setString(1,phone);
			procCall.setString(2,city);
			procCall.setString(3,username);
			procCall.setString(4,password);
			procCall.setString(5,workspace);
			procCall.registerOutParameter(6, java.sql.Types.FLOAT);
			procCall.executeUpdate(); 
			float userId = procCall.getFloat(6); 
			result=userId;
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally{
			session.close();
		}
		JSONObject jsonObject = new JSONObject();
		jsonObject.put("status", result);
		jsonObject.put("type", "regist_1");
		jsonObject.put("msg", result > 0 ? "注册成功" : "注册失败");
		jsonObject.put("data", "");
		return Result.success(jsonObject.toString());	
	}
	//check login and get token
	@Transactional
	@RequestMapping(value = "/login", method = RequestMethod.POST)
	@ResponseBody
	@ApiOperation(value = "check login and get token", notes = "check login and get token", httpMethod = "GET", produces = "application/json")
	public ResponseMessage<?> login(HttpServletRequest req, @RequestParam String loginname, @RequestParam String password) throws Exception {
		logger.info("login[{}]", loginname);
		System.out.println("=============客户端登录=========");

		// check loginname
		if (StringUtil.isEmpty(loginname)) {
			return Result.error("用户账号不能为空!");
		}
		// check password
		if (StringUtils.isEmpty(password)) {
			return Result.error("用户密码不能为空!");
		}
		Assert.notNull(loginname, "username can not be empty");
		Assert.notNull(password, "password can not be empty");

		SysUserEntity appUser = appuserSerive.checkAppuser(loginname,
				password);
		// TSUser user = userService.checkUserExits(username, password);
		if (oConvertUtils.isEmpty(appUser)) {
			// 提示用户名或密码错误
			logger.info("login,username or password wrong[{}]", loginname);
			return Result.error("您填写的用户名或密码不正确，请再次尝试。");
		}

		// creat a token and save user login states
		String token = tokenManager.createAppToken(appUser);
		LogUtil.info("======user【" + appUser.getLoginname() + "】token is【" + token
				+ "】,term of validity until【" + JwtConstants.TOKEN_EXPIRES_HOUR + "】hour======");

		// save leatest token
		JSONObject jsonObject = new JSONObject();
		jsonObject.put("token",token);
		return Result.success(jsonObject);
	}

	/**
	 * 发送手机短信验证码
	 * 
	 * @param phoneNum
	 * @return
	 * @throws UnsupportedEncodingException
	 * @throws ClientException
	 */
	@RequestMapping(value = "sendSmsCode", method = RequestMethod.POST)
	@ResponseBody
	@ApiOperation(value = "发送手机验证码", produces = "application/json", httpMethod = "POST")
	public ResponseMessage<?> sendSmsCode(@RequestParam("phone") String phone)
			throws UnsupportedEncodingException {
		String result = tokenManager.saveMsgCode(phone);
		LogUtil.info("======用户【" + phone + "】的短信编码【" + result + "】,有效期为【"
				+ JwtConstants.IMGCODE_EXPIRES_MINUTES + "】分钟======");
		return Result.success(result);
	}

	/**
	 * 发送图形验证码
	 * 
	 * @param phoneNum
	 * @return
	 * @throws UnsupportedEncodingException
	 * @throws ClientException
	 */
//	@RequestMapping(value = "getImgCode", method = RequestMethod.GET)
//	@ResponseBody
//	@ApiOperation(value = "发送图形验证码", produces = "application/json", httpMethod = "GET")
//	public ResponseMessage<?> getImgCode(@RequestParam("phone") String phone)
//			throws UnsupportedEncodingException {
//
//		String imgCode = tokenManager.saveImgCode(phone);
//		LogUtil.info("======用户【" + phone + "】的code【" + imgCode + "】,有效期为【"
//				+ JwtConstants.IMGCODE_EXPIRES_MINUTES + "】分钟======");
//
//		return Result.success(imgCode);
//	}

	/**
	 * change password
	 * 
	 * @return
	 */
	@RequestMapping(value = "/updatePwd", method = RequestMethod.POST)
	@ResponseBody
	public ResponseMessage<?> updatePwd(HttpServletRequest request,
			@RequestParam("phone") String phone,
			@RequestParam("password") String password) {

		logger.info("[" + IpUtil.getIpAddr(request) + "][changpassword] start");
//		String password = oConvertUtils.getString(request
//				.getParameter("password"));
			String sql = "update  sys_user set password=? where loginname=?";
			password = MD5.GetMD5Code(password);
			Integer result = systemService.executeSql(sql, password, phone);
			JSONObject jsonObject = new JSONObject();
			jsonObject.put("status", result);
			jsonObject.put("type", "updatePwd");
			jsonObject.put("msg", result > 0 ? "修改成功" : "修改失败");
			jsonObject.put("data", "");
			return Result.success(jsonObject.toString());
	}

}
